package com.eva.databuilder.bo;

import com.alibaba.fastjson.JSON;
import com.eva.databuilder.builders.AbstractTemplateDataBuilder;
import com.eva.databuilder.enums.TemplateDataBuilderConfigEnum;
import com.eva.framework.common.utils.Utils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
@ApiModel("模板预设数据集合")
public class TemplatePresetDataList {

    private int index;

    private List<TemplatePresetData> presetDataList = new ArrayList<>();

    /**
     * 添加预设数据
     *
     * @param presetData 预设数据
     */
    public void add (TemplatePresetData presetData) {
        presetDataList.add(presetData);
    }

    /**
     * 判断是否存在下一个数据定义
     *
     * @return boolean
     */
    public boolean hasNext () {
        return index < presetDataList.size();
    }

    /**
     * 获取下一个数据定义
     *
     * @return String
     */
    public TemplatePresetData next () {
        if (index >= presetDataList.size()) {
            throw new RuntimeException("没有下一个数据定义");
        }
        TemplatePresetData next = presetDataList.get(index);
        // 获取数据编码
        String dataCode = next.getCode();
        // 获取数据的构建配置
        TemplateDataBuilderConfigEnum builderConfig = TemplateDataBuilderConfigEnum.getByCode(dataCode);
        // 获取构建器实例
        if (builderConfig != null) {
            next.setEnabledCache(builderConfig.getEnabledCache());
            next.setBuilder(Utils.SpringContext.getBean(builderConfig.getBuilder()));
        }
        this.index++;
        return next;
    }

    @Data
    @ApiModel("模板预设数据")
    public static class TemplatePresetData {

        @ApiModelProperty("预设数据编码")
        private String code;

        @ApiModelProperty("是否启用缓存")
        private Boolean enabledCache;

        @ApiModelProperty("预设数据参数")
        private TemplateDataParameters parameters;

        @ApiModelProperty("数据构建器")
        private AbstractTemplateDataBuilder<?> builder;

        /**
         * 设置参数值
         * 优先级：数据预设的参数 > 请求携带的参数
         *
         * @param requestParameters 请求携带的参数
         * @param targetPresetParameters 目标数据预设的参数，如栏目预设的参数
         */
        public void setParameters (
                TemplateDataParameters requestParameters,
                List<TemplateDataParameters.PresetParameter> targetPresetParameters
        ) {
            // 拷贝请求携带的参数，使每个数据项的获取参数都是独立的
            TemplateDataParameters newRequestParameters = requestParameters == null
                    ? new TemplateDataParameters() : JSON.parseObject(JSON.toJSONString(requestParameters), TemplateDataParameters.class);
            this.parameters = newRequestParameters;
            // 优先从目标数据预设的参数中获取
            if (targetPresetParameters != null) {
                for (TemplateDataParameters.PresetParameter presetParameter : targetPresetParameters) {
                    newRequestParameters.assignIfNotEmpty(presetParameter.getName(), presetParameter.getValue());
                }
            }
        }
    }
}
